#pragma once


#if defined(WIN32) || defined(WIN64)
	#include <windows.h>
	#define sem_type HANDLE
#else 
	#include <semaphore.h> 
	typedef sem_t *sem_type;
#endif
	 

////sem

class CMySem
{
public:
	CMySem() { 
		sem = NULL ;
		Thread_create_sem();
	}
	~CMySem()
	{
		Thread_destroy_sem();
	} 

	int Thread_wait_sem()
	{ 
		int rc = -1; 
 
		#if defined(WIN32) || defined(WIN64)
			rc = WaitForSingleObject(sem, 0);  
		#else 
			rc = sem_wait(sem ); 
		#endif
			 
 		return rc;
	}

	int Thread_wait_sem( int timeout )
	{ 
		int rc = -1;
		
		#if !defined(WIN32) && !defined(WIN64)  
				int i = 0;
				int interval = 10000; /* 10000 microseconds: 10 milliseconds */
				int count = (1000 * timeout) / interval; /* how many intervals in timeout period */ 
		#endif
 
		#if defined(WIN32) || defined(WIN64)
			rc = WaitForSingleObject(sem, timeout < 0 ? 0 : timeout); 
		#else  
			while (++i < count && (rc = sem_trywait(sem)) != 0)
			{
				if (rc == -1 && ((rc = errno) != EAGAIN))
				{
					rc = 0;
					break;
				}
				usleep(interval); /* microseconds - .1 of a second */
			} 
		#endif
			 
 		return rc;
	}

	int Thread_check_sem( )
	{
		#if defined(WIN32) || defined(WIN64)
			return WaitForSingleObject(sem, 0) == WAIT_OBJECT_0; 
		#else
			int semval = -1;
			sem_getvalue(sem, &semval);
			return semval > 0;
		#endif
	}

	int Thread_post_sem( )
	{
		int rc = 0;
		 
		#if defined(WIN32) || defined(WIN64)
			if (SetEvent(sem) == 0)
				rc = GetLastError(); 
		#else
			if (sem_post(sem) == -1)
				rc = errno;
		#endif
			 
		return rc;
	}

	
private:
	sem_type   sem;

	void Thread_create_sem(void)
	{
		//sem_type sem = NULL;
		int rc = 0;
	 
		#if defined(WIN32) || defined(WIN64)
			sem = CreateEvent(
						NULL,               /* default security attributes */
						FALSE,              /* manual-reset event? */
						FALSE,              /* initial state is nonsignaled */
						NULL                /* object name */
						); 
		#else
			sem = (sem_type)malloc(sizeof(sem_t));
			rc = sem_init(sem, 0, 0);
		#endif 
	}

	int Thread_destroy_sem( )
	{
		int rc = 0;
		 
		#if defined(WIN32) || defined(WIN64)
			rc = CloseHandle(sem); 
		#else
			rc = sem_destroy(sem);
			free(sem);
		#endif 

		return rc;
	}
};
 